package py.fpuna.aiwa.compraventa.droid.db;

import java.util.ArrayList;

import py.fpuna.aiwa.compraventa.droid.db.CompraVentaContract.Cliente;
import py.fpuna.aiwa.compraventa.droid.db.CompraVentaContract.DetalleVenta;
import py.fpuna.aiwa.compraventa.droid.db.CompraVentaContract.Producto;
import py.fpuna.aiwa.compraventa.droid.db.CompraVentaContract.Tables;
import py.fpuna.aiwa.compraventa.droid.db.CompraVentaContract.Usuario;
import py.fpuna.aiwa.compraventa.droid.db.CompraVentaContract.Venta;
import android.content.ContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.OperationApplicationException;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

public class CompraVentaProvider extends ContentProvider {
	private CompraVentaDatabase mOpenHelper;

	private static final UriMatcher sUriMatcher;
	private static final int USUARIO = 100;
	private static final int USUARIO_ID = 101;
	private static final int CLIENTE = 200;
	private static final int CLIENTE_ID = 201;
	private static final int PRODUCTO = 300;
	private static final int PRODUCTO_ID = 301;
	private static final int VENTA = 400;
	private static final int VENTA_ID = 401;
	private static final int DETALLE_VENTA = 500;
	private static final int DETALLE_VENTA_ID = 501;

	
	static {
		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

		sUriMatcher.addURI(CompraVentaContract.CONTENT_AUTHORITY, 
				CompraVentaContract.URI_PATH_USUARIOS,
				USUARIO);
		sUriMatcher.addURI(CompraVentaContract.CONTENT_AUTHORITY, 
				CompraVentaContract.URI_PATH_USUARIOS + "/*",
				USUARIO_ID);
		sUriMatcher.addURI(CompraVentaContract.CONTENT_AUTHORITY, 
				CompraVentaContract.URI_PATH_CLIENTES,
				CLIENTE);
		sUriMatcher.addURI(CompraVentaContract.CONTENT_AUTHORITY, 
				CompraVentaContract.URI_PATH_CLIENTES + "/*",
				CLIENTE_ID);
		sUriMatcher.addURI(CompraVentaContract.CONTENT_AUTHORITY, 
				CompraVentaContract.URI_PATH_PRODUCTOS,
				PRODUCTO);
		sUriMatcher.addURI(CompraVentaContract.CONTENT_AUTHORITY, 
				CompraVentaContract.URI_PATH_PRODUCTOS + "/*",
				PRODUCTO_ID);
		sUriMatcher.addURI(CompraVentaContract.CONTENT_AUTHORITY, 
				CompraVentaContract.URI_PATH_VENTAS,
				VENTA);
		sUriMatcher.addURI(CompraVentaContract.CONTENT_AUTHORITY, 
				CompraVentaContract.URI_PATH_VENTAS + "/*",
				VENTA_ID);
		sUriMatcher.addURI(CompraVentaContract.CONTENT_AUTHORITY, 
				CompraVentaContract.URI_PATH_DETALLE_VENTAS,
				DETALLE_VENTA);
		sUriMatcher.addURI(CompraVentaContract.CONTENT_AUTHORITY, 
				CompraVentaContract.URI_PATH_DETALLE_VENTAS + "/*",
				DETALLE_VENTA_ID);
	}

	@Override
	public boolean onCreate() {
		mOpenHelper = new CompraVentaDatabase(getContext());
		return true;
	}

	@Override
	public String getType(Uri uri) {
		switch (sUriMatcher.match(uri)) {
			case USUARIO:
				return Usuario.CONTENT_TYPE;
			case USUARIO_ID:
				return Usuario.CONTENT_ITEM_TYPE;
			case CLIENTE:
				return Cliente.CONTENT_TYPE;
			case CLIENTE_ID:
				return Cliente.CONTENT_ITEM_TYPE;
			case PRODUCTO:
				return Producto.CONTENT_TYPE;
			case PRODUCTO_ID:
				return Producto.CONTENT_ITEM_TYPE;
			case VENTA:
				return Venta.CONTENT_TYPE;
			case VENTA_ID:
				return Venta.CONTENT_ITEM_TYPE;
			case DETALLE_VENTA:
				return DetalleVenta.CONTENT_TYPE;
			case DETALLE_VENTA_ID:
				return DetalleVenta.CONTENT_ITEM_TYPE;
			default:
				throw new UnsupportedOperationException("Unknown uri: " + uri);
		}
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SQLiteDatabase db = mOpenHelper.getReadableDatabase();
		SelectionBuilder builder = buildExpandedSelection(uri, selection, selectionArgs);
		return builder.query(db, projection, sortOrder);
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		
		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		
		switch (sUriMatcher.match(uri)) {
			case USUARIO:
				Integer idUsuario = insertOrThrow(uri, values, db, Tables.USUARIO);
				return Usuario.buildUri(idUsuario);
			case CLIENTE:
				Integer idCliente = insertOrThrow(uri, values, db, Tables.CLIENTE);
				return Cliente.buildUri(idCliente);
			case PRODUCTO:
				Integer idProducto = insertOrThrow(uri, values, db, Tables.PRODUCTO);
				return Producto.buildUri(idProducto);
			case VENTA:
				Integer idVenta = insertOrThrow(uri, values, db, Tables.VENTA);
				return Venta.buildUri(idVenta);
			case DETALLE_VENTA:
				Integer idDetalleVenta = insertOrThrow(uri, values, db, Tables.DETALLE_VENTA);
				return DetalleVenta.buildUri(idDetalleVenta);
			default:
				throw new UnsupportedOperationException("Unknown uri: " + uri);
		}
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		
		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		
		SelectionBuilder builder = buildSimpleSelection(uri, selection,
				selectionArgs);
		int result = builder.update(db, values);
		notifyChange(uri);
		return result;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		SelectionBuilder builder = buildSimpleSelection(uri, selection,
				selectionArgs);
		int result = builder.delete(db);
		notifyChange(uri);
		return result;
	}


	@Override
	public ContentProviderResult[] applyBatch(
			ArrayList<ContentProviderOperation> operations)
			throws OperationApplicationException {
		final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		db.beginTransaction();
		try {
			final int n = operations.size();
			final ContentProviderResult[] results = new ContentProviderResult[n];
			for (int i = 0; i < n; i++) {
				results[i] = operations.get(i).apply(this, results, i);
			}
			db.setTransactionSuccessful();
			return results;
		} finally {
			db.endTransaction();
		}
	}

	private SelectionBuilder buildSimpleSelection(Uri uri) {
		SelectionBuilder builder = new SelectionBuilder();
		switch (sUriMatcher.match(uri)) {
		
		case USUARIO:
			return builder.table(Tables.USUARIO);
		case USUARIO_ID:
			String usuarioId = Usuario.getId(uri);
			return builder.table(Tables.USUARIO).where(Usuario._ID + " = ?", usuarioId);
		case CLIENTE:
			return builder.table(Tables.CLIENTE);
		case CLIENTE_ID:
			String clienteId = Cliente.getId(uri);
			return builder.table(Tables.CLIENTE).where(Cliente._ID + " = ?", clienteId);
		case PRODUCTO:
			return builder.table(Tables.PRODUCTO);
		case PRODUCTO_ID:
			String productoId = Producto.getId(uri);
			return builder.table(Tables.PRODUCTO).where(Producto._ID + " = ?", productoId);
		case VENTA:
			return builder.table(Tables.VENTA);
		case VENTA_ID:
			String ventaId = Venta.getId(uri);
			return builder.table(Tables.VENTA).where(Venta._ID + " = ?", ventaId);
		case DETALLE_VENTA:
			return builder.table(Tables.DETALLE_VENTA);
		case DETALLE_VENTA_ID:
			String detalleVentaId = DetalleVenta.getId(uri);
			return builder.table(Tables.DETALLE_VENTA).where(DetalleVenta._ID + " = ?", detalleVentaId);
		default:
			throw new UnsupportedOperationException("Unknown uri: " + uri);
		}
	}

	private SelectionBuilder buildSimpleSelection(Uri uri, String selection,
			String[] selectionArgs) {
		return buildSimpleSelection(uri).where(selection, selectionArgs);
	}

	private SelectionBuilder buildExpandedSelection(Uri uri) {
		// final SelectionBuilder builder = new SelectionBuilder();
		switch (sUriMatcher.match(uri)) {
		default:
			return buildSimpleSelection(uri);
		}
	}

	private SelectionBuilder buildExpandedSelection(Uri uri, String selection,
			String[] selectionArgs) {
		return buildExpandedSelection(uri).where(selection, selectionArgs);
	}

	private Integer insertOrThrow(Uri uri, ContentValues values,
			SQLiteDatabase db, String table) {
		Integer id = (int) db.insertOrThrow(table, null, values);
		notifyChange(uri);
		return id;
	}

	private void notifyChange(Uri uri) {
		getContext().getContentResolver().notifyChange(uri, null, false);
	}
	// private interface Qualified {
	// }
}